<template>
    <div class="container">
        <div class="conn">
            <el-button size="small" :type="isConnect ? 'success' : 'danger'" circle />
            <el-input v-model="wsUrl" size="small" :disabled="isConnect" placeholder="输入服务器地址"
                @keyup.enter.native="connectWebSocket" />
            <el-button type="primary" size="small" @click="connectWebSocket">{{ isConnect ? '断开' : '连接' }}</el-button>
        </div>
        <div class="main" v-if="isGame">
            <div class="board">
                <div v-for="(cell, index) in JSON.parse(currentGame.game_data)" :key="index" class="cell"
                    @click="play(index)">
                    <div class="black" v-if="cell === '2'"></div>
                    <div class="white" v-if="cell === '1'"></div>
                </div>
            </div>
            <div class="option">
                <div class="top">
                    <span :class="currentGame.current === currentGame.player1 ? 'currentPlayer' : ''"
                        @click="setUser(1)">{{ currentGame.player1
                            === '' ? '等待加入' : currentGame.player1 }}</span> VS
                    <span :class="currentGame.current === currentGame.player2 ? 'currentPlayer' : ''"
                        @click="setUser(2)">{{ currentGame.player2
                            === '' ? '等待加入' : currentGame.player2 }}</span>
                </div>
                <div class="bottom">
                    <el-button size="small" type="primary" @click="backList">返回</el-button>
                    <el-button size="small" type="primary" @click="gameStart"
                        v-if="currentGame.status === '0'">开始游戏</el-button>
                    <el-button size="small" type="success" v-if="currentGame.status === '2'">赢家: {{ currentGame.winner
                        }}</el-button>
                </div>
            </div>

        </div>
        <div class="main" v-show="!isGame">
            <div class="match" @click="goMatch(1)" v-if="isConnect">
                新建游戏
            </div>
            <div class="match" v-for="(game, index) in gameList" :key="index" @click="goMatch(0, game)">
                <div class="time">{{ game.create_time }}</div>
                <div class="other">
                    <span class="player">{{ game.player1 === '' ? '等待加入' : game.player1 }} VS {{ game.player2 === '' ?
                        '等待加入' : game.player2 }}</span>
                    <span
                        :class="game.status === '2' ? 'red_status' : (game.status === '1' ? 'green_status' : 'orange_status')">{{
                            game.status === '0' ? '未开始' :
                                (game.status === '1' ? '进行中' : '已结束')
                        }}</span>
                </div>
                <div class="number">{{ game.jid }}</div>
            </div>
        </div>
    </div>
</template>
<script setup>
import { CloseBold, CircleCheck } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { ref } from 'vue'
const socket = ref(null);

const isConnect = ref(false)
const wsUrl = ref('')
const isGame = ref(false)

const gameList = ref([])
const currentGame = ref(null)
const ip = ref(null)

const connectWebSocket = () => {
    if (isConnect.value) {
        socket.value?.close()
        isConnect.value = false
        isGame.value = false
    } else {
        try {
            socket.value = new WebSocket('ws://' + wsUrl.value);
        } catch (error) {
            ElMessage.error({ message: '连接失败，检查服务器地址！', duration: 800 })
        }
        socket.value.onopen = function (event) {
            ElMessage.success({ message: '服务器已连接！', duration: 800 })
            isConnect.value = true
        };

        socket.value.onerror = function (error) {
            ElMessage.error({ message: '连接出错！', duration: 800 })
        };

        socket.value.onmessage = function (event) {
            let data = JSON.parse(event.data)
            if (data.type === 'all') {
                gameList.value = data.fives
                ip.value = data.ip
                // console.log('ip-----',ip.value);
            } else if (data.type === 'addFiveCompleted') {
                gameList.value = data.fives
            } else if (data.type === 'updateFiveCompleted') {
                // console.log('updateJingCompleted', data);
                if(currentGame.value && currentGame.value.id === data.five.id){
                    currentGame.value = data.five
                    if(currentGame.value.status =='2' && currentGame.value.winner != '平局'){
                        ElMessage.success({ 
                            message: '恭喜' + currentGame.value.winner + '获胜！', 
                            grouping: true,
                            duration: 1500 })
                    }
                }
                gameList.value = data.fives
            } else if (data.type === 'getFivesCompleted') {
                gameList.value = data.fives
            }

        };

        socket.value.onclose = function () {
            ElMessage.error({ message: '服务器已断开！', duration: 800 })
            isConnect.value = false
        };
    }
}
const sendMessage = (type, msg) => {
    if (socket.value && socket.value.readyState === WebSocket.OPEN) {
        let obj = {
            type: type,
            msg: msg,
            time: new Date().toLocaleString(),
        }
        socket.value.send(JSON.stringify(obj));
    } else {
        ElMessage.error({ message: '未连接服务器！', duration: 800 })
    }
}
const goMatch = (flag, game) => {
    if (isConnect.value === false) {
        ElMessage.error({ message: '请先连接服务器！', duration: 800 })
        return;
    } else {
        if (flag === 1) {
            let data = {
                game_data: JSON.stringify(Array(225).fill(null)),
                player1: '',
                player2: '',
                create_time: new Date().toLocaleString(),
                status: 0,
                current: '',
                winner: ''
            }
            sendMessage('addFive', JSON.stringify(data))
        } else {
            currentGame.value = game
            isGame.value = true
        }
    }

}
const setUser = (userId) => {
    if (currentGame.value.status !== '0') {
        ElMessage.error({ message: '游戏已开始！', duration: 800 })
        return;
    } else {
        if (userId === 1) {
            if (currentGame.value.player1 === '') {
                currentGame.value.player1 = ip.value;
                if (currentGame.value.player2 === ip.value) {
                    currentGame.value.player2 = '';
                }
            } else {
                ElMessage.error({ message: '已存在玩家！', duration: 800 })
            }

        } else {
            if (currentGame.value.player2 === '') {
                currentGame.value.player2 = ip.value;
                if (currentGame.value.player1 === ip.value) {
                    currentGame.value.player1 = '';
                }
            } else {
                ElMessage.error({ message: '已存在玩家！', duration: 800 })
            }
        }
    }
    updateFive()
}
const gameStart = () => {
    if (currentGame.value.player1 === '' || currentGame.value.player2 === '') {
        ElMessage.error({ message: '玩家不齐！', duration: 800 })
        return;
    } else {
        currentGame.value.status = '1';
        const random = Math.random();
        currentGame.value.current = random < 0.5 ? currentGame.value.player1 : currentGame.value.player2;
    }
    updateFive()
}
function play(index) {
    if (currentGame.value.status === '0') {
        ElMessage.error({ message: '游戏未开始！', duration: 800 })
        return;
    } else if (currentGame.value.status === '2') {
        ElMessage.error({ message: '游戏已结束！', duration: 800 })
        return;
    } else if (currentGame.value.current !== ip.value) {
        ElMessage.error({ message: '不是你的回合！', duration: 800 })
        return;
    } else if (JSON.parse(currentGame.value.game_data)[index] !== null) {
        ElMessage.error({ message: '该位置已存在棋子！', duration: 800 })
        return;
    } else {
        if (currentGame.value.player1 === ip.value) {
            let gameData = JSON.parse(currentGame.value.game_data);
            gameData[index] = '1';
            currentGame.value.game_data = JSON.stringify(gameData);
            currentGame.value.current = currentGame.value.player2;
        } else {
            let gameData = JSON.parse(currentGame.value.game_data);
            gameData[index] = '2';
            currentGame.value.game_data = JSON.stringify(gameData);
            currentGame.value.current = currentGame.value.player1;
        }
        updateFive()
        checkWin();
    }
}
function checkWin() {
    const n = 15;
    // 检查横向
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n - 4; j++) {
            let sameCount = 1;
            let firstValue = JSON.parse(currentGame.value.game_data)[i * n + j];
            if (firstValue !== null) {
                for (let k = j + 1; k < j + 5; k++) {
                    if (JSON.parse(currentGame.value.game_data)[i * n + k] === firstValue) {
                        sameCount++;
                    } else {
                        break;
                    }
                }
                if (sameCount === 5) {
                    currentGame.value.status = '2';
                    currentGame.value.winner = ip.value;
                    updateFive()
                    // ElMessage.success({ message: '恭喜' + ip.value + '获胜！', duration: 800 })
                    return;
                }
            }
        }
    }
    // 检查纵向
    for (let i = 0; i < n - 4; i++) {
        for (let j = 0; j < n; j++) {
            let sameCount = 1;
            let firstValue = JSON.parse(currentGame.value.game_data)[i * n + j];
            if (firstValue !== null) {
                for (let k = i + 1; k < i + 5; k++) {
                    if (JSON.parse(currentGame.value.game_data)[k * n + j] === firstValue) {
                        sameCount++;
                    } else {
                        break;
                    }
                }
                if (sameCount === 5) {
                    currentGame.value.status = '2';
                    currentGame.value.winner = ip.value;
                    updateFive()
                    // ElMessage.success({ message: '恭喜' + ip.value + '获胜！', duration: 800 })
                    return;
                }
            }
        }
    }
    // 检查正对角线
    for (let i = 0; i < n - 4; i++) {
        for (let j = 0; j < n - 4; j++) {
            let sameCount = 1;
            let firstValue = JSON.parse(currentGame.value.game_data)[i * n + j];
            if (firstValue !== null) {
                for (let k = 1; k < 5; k++) {
                    if (JSON.parse(currentGame.value.game_data)[(i + k) * n + j + k] === firstValue) {
                        sameCount++;
                    } else {
                        break;
                    }
                }
                if (sameCount === 5) {
                    currentGame.value.status = '2';
                    currentGame.value.winner = ip.value;
                    updateFive()
                    // ElMessage.success({ message: '恭喜' + ip.value + '获胜！', duration: 800 })
                    return;
                }
            }
        }
    }
    // 检查反对角线
    for (let i = 4; i < n; i++) {
        for (let j = 0; j < n - 4; j++) {
            let sameCount = 1;
            let firstValue = JSON.parse(currentGame.value.game_data)[i * n + j];
            if (firstValue !== null) {
                for (let k = 1; k < 5; k++) {
                    if (JSON.parse(currentGame.value.game_data)[(i - k) * n + j + k] === firstValue) {
                        sameCount++;
                    } else {
                        break;
                    }
                }
                if (sameCount === 5) {
                    currentGame.value.status = '2';
                    currentGame.value.winner = ip.value;
                    updateFive()
                    // ElMessage.success({ message: '恭喜' + ip.value + '获胜！', duration: 800 })
                    return;
                }
            }
        }
    }
    return null;
}
const backList = () => {
    isGame.value = false;
    sendMessage('getFives')
}
const updateFive = () => {
    sendMessage('updateFive', JSON.stringify(currentGame.value))
}
</script>
<style lang="less" scoped>
.container {
    width: 100%;
    height: 100%;
    padding: 10px;
    // background: #fff;
    // border: 1px solid #333;
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    color: #333;

    .conn {
        -webkit-app-region: no-drag;
        width: 100%;
        height: 30px;
        display: flex;
        align-items: center;
        margin-bottom: 5px;
        justify-content: space-between;

        .el-input {
            margin: 0 5px;
            flex: 1;
        }
    }

    .main {
        width: 100%;
        height: 100%;
        overflow-x: hidden;
        overflow-y: scroll;

        // 隐藏滚动条
        &::-webkit-scrollbar {
            display: none;
        }

        .match {
            border: 1px dashed #ccc;
            border-radius: 8px;
            padding: 0 5px;
            font-size: 14px;
            cursor: pointer;
            transition-duration: .3s;
            margin-bottom: 5px;
            position: relative;

            &:hover {
                background: #ccc;
            }

            .number {
                position: absolute;
                font-size: 20px;
                color: #e74514;
                top: 5px;
                right: 100px;
            }

            .time {
                font-size: 10px;
                font-weight: 700;
                color: #002f5d;
            }

            .other {
                display: flex;

                .player {
                    margin-right: auto;
                    color: #333;
                }

                .red_status {
                    color: rgb(255, 4, 4);
                }

                .green_status {
                    color: rgb(13, 243, 13);
                }

                .orange_status {
                    color: rgb(252, 195, 41);
                }
            }

        }

        .board {
            width: 100%;
            padding: 0 10px;
            display: flex;
            flex-wrap: wrap;
            justify-content: center;

            .cell {
                width: 22px;
                height: 22px;
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: pointer;
                //   border: 1px solid #FF4351;
                //   background-color: #ee8309;
                background-image: url(../../assets/棋盘.png);
                background-size: contain;
                transition-duration: .5s;
                //   margin: 5px;
                //   border-radius: 8px;
                color: #fff;
                font-size: 50px;

                &:hover {
                    border: 1px solid #f10e0e;
                }

                .black {
                    width: 18px;
                    height: 18px;
                    border-radius: 50%;
                    background-color: #333;
                }

                .white {
                    width: 18px;
                    height: 18px;
                    border-radius: 50%;
                    background-color: #fff;
                }
            }
        }

        .option {
            color: #333;
            display: flex;
            flex-direction: column;
            align-items: center;

            .top {
                margin: 3px 0;

                span {
                    border: 1px solid #333;
                    border-radius: 5px;
                    font-size: 13px;
                    padding: 3px;
                    cursor: pointer;
                    transition-duration: .3s;

                    &:hover {
                        background: #333;
                        color: #fff;
                    }
                }

                .currentPlayer {
                    background: #65a1df;
                    color: #fff;
                }
            }
        }
    }
}
</style>